package com.snow.vpnclient.activity;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.alibaba.fastjson.JSON;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.snow.vpnclient.R;
import com.snow.vpnclient.databinding.ActivityMainBinding;
import com.snow.vpnclient.dto.AppConfigDto;
import com.snow.vpnclient.util.Logger;
import com.snow.vpnclient.view.MyWebView;
import com.tencent.smtt.export.external.interfaces.PermissionRequest;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

public class MainActivity extends AppCompatActivity {

    private WindowManager windowManager;

    private WindowManager.LayoutParams layoutParams;

    private View floatView;

    private static final int REQUEST_RECORD_AUDIO_PERMISSION = 18080;

    private static final String SP_APP_CONFIG = "SP_APP_CONFIG";

    private ActivityMainBinding binding;

    private boolean doubleBackToExitPressedOnce = false;

    private MyWebView webView;

    private ActivityResultLauncher<String> requestPermissionLauncher =
            registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
                if (isGranted) {
                    ToastUtils.showShort("授权成功");
                    // 用户已授权，执行相关操作
                } else {
                    ToastUtils.showShort("授权失败");
                    // 用户未授权，处理未授权情况
                }
            });

    // 请求授权方法
    private void requestStoragePermission() {
        // 调用 launcher 请求权限
        requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        requestStoragePermission();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            boolean isHave = Settings.canDrawOverlays(getApplicationContext());
            if (!isHave) {
                startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 10086);
            }
        }

        initData();
        binding.btnSave.setOnClickListener(view -> {
            AppConfigDto appConfigDto = new AppConfigDto();
            appConfigDto.setTypeGet(binding.editTypeGet.getText().toString());
            appConfigDto.setUrlPre(binding.editUrlPre.getText().toString());
            appConfigDto.setPythonUrl(binding.editPythonUrl.getText().toString());
            appConfigDto.setBackUrl(binding.editBackUrl.getText().toString());
            appConfigDto.setBackSocket(binding.editBackSocket.getText().toString());
            appConfigDto.setPushPort(binding.editPushPort.getText().toString());
            appConfigDto.setPullPort(binding.editPullPort.getText().toString());
            appConfigDto.setWidth(binding.editWidth.getText().toString());
            appConfigDto.setHeight(binding.editHeight.getText().toString());
            SPUtils.getInstance().put(SP_APP_CONFIG, JSON.toJSONString(appConfigDto));
            ToastUtils.showShort("保存成功");
            sendAppConfigToJs();
        });

        binding.btnOpen.setOnClickListener(view -> {
            if (floatView != null) {
                return;
            }

            windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
            layoutParams = new WindowManager.LayoutParams();

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
            } else {
                layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
            }
            layoutParams.gravity = Gravity.LEFT | Gravity.CENTER;
            layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
            layoutParams.format = PixelFormat.RGBA_8888;

            setLayoutParamWidthHeight();

            layoutParams.x = 0;
            layoutParams.y = 0;

            LayoutInflater layoutInflater = LayoutInflater.from(getApplicationContext());
            floatView = layoutInflater.inflate(R.layout.floating_view, null);

            webView = floatView.findViewById(R.id.web_view);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
            }
            webView.setBackgroundColor(Color.TRANSPARENT);
            webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setAllowFileAccess(true);
            webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
            webView.getSettings().setAllowFileAccessFromFileURLs(true);
            webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
//            webView.getSettings().setMixedContentMode(webView.getSettings().MIXED_CONTENT_ALWAYS_ALLOW);
            webView.setWebChromeClient(new WebChromeClient() {
                @Override
                public void onPermissionRequest(PermissionRequest request) {
                    ToastUtils.showShort("网页端的权限请求");
                    // 在这里处理网页端的权限请求
                    request.grant(request.getResources());

                    if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
                            ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.MODIFY_AUDIO_SETTINGS) != PackageManager.PERMISSION_GRANTED) {
                        ActivityCompat.requestPermissions(MainActivity.this, new String[]{
                                        Manifest.permission.RECORD_AUDIO,
                                        Manifest.permission.MODIFY_AUDIO_SETTINGS},
                                REQUEST_RECORD_AUDIO_PERMISSION);
                    }
                }
            });

            webView.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    super.onPageStarted(view, url, favicon);
                    Logger.d("拦截URL：" + url);
                }

                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    // 判断url链接中是否含有某个字段，如果有就执行指定的跳转（不执行跳转url链接），如果没有就加载url链接
                    Logger.d("拦截URL：" + url);
//                    return super.shouldOverrideUrlLoading(view, url);
                    return false;
                }
            });
//            webView.loadUrl("https://yilanmeta.com/");
            webView.loadUrl("file:///android_asset/index.html");
            sendAppConfigToJs();

            windowManager.addView(floatView, layoutParams);

            floatView.setOnTouchListener(new FloatingOnTouchListener());
        });

        binding.btnClose.setOnClickListener(view -> {
            if (floatView != null) {
                windowManager.removeViewImmediate(floatView);
                webView.loadUrl("");
                floatView = null;
            }
        });
    }

    private void sendAppConfigToJs() {
        if (webView != null) {
            String appConfig = SPUtils.getInstance().getString(SP_APP_CONFIG);
            String javascriptCode = "javascript:setAppConfig('" + appConfig + "');";
            webView.evaluateJavascript(javascriptCode, null);
        }
    }

    private void setLayoutParamWidthHeight() {
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

        String appConfig = SPUtils.getInstance().getString(SP_APP_CONFIG);
        Logger.d("appConfig=" + appConfig);
        if (!StringUtils.isEmpty(appConfig)) {
            AppConfigDto configDto = JSON.parseObject(appConfig, AppConfigDto.class);
            if (configDto != null) {
                if (!StringUtils.isEmpty(configDto.getWidth())) {
                    try {
                        layoutParams.width = Integer.parseInt(configDto.getWidth());
                    } catch (Exception ignore) {
                    }
                }
                if (!StringUtils.isEmpty(configDto.getHeight())) {
                    try {
                        layoutParams.height = Integer.parseInt(configDto.getHeight());
                    } catch (Exception ignore) {
                    }
                }
            }
        }

        Logger.d("layoutParams.width=" + layoutParams.width);
        Logger.d("layoutParams.height=" + layoutParams.height);
    }

    private void initData() {
        String appConfig = SPUtils.getInstance().getString(SP_APP_CONFIG);
        if (StringUtils.isEmpty(appConfig)) {
            return;
        }

        AppConfigDto configDto = JSON.parseObject(appConfig, AppConfigDto.class);
        if (configDto == null) {
            return;
        }

        binding.editTypeGet.setText(configDto.getTypeGet());
        binding.editUrlPre.setText(configDto.getUrlPre());
        binding.editPythonUrl.setText(configDto.getPythonUrl());
        binding.editBackUrl.setText(configDto.getBackUrl());
        binding.editBackSocket.setText(configDto.getBackSocket());
        binding.editPushPort.setText(configDto.getPushPort());
        binding.editPullPort.setText(configDto.getPullPort());
        binding.editWidth.setText(configDto.getWidth());
        binding.editHeight.setText(configDto.getHeight());
    }

    private class FloatingOnTouchListener implements View.OnTouchListener {

        private int x;

        private int y;

        //标记是否执行move事件 如果执行了move事件  在up事件的时候判断悬浮窗的位置让悬浮窗处于屏幕左边或者右边

        private boolean isScroll;

        //标记悬浮窗口是否移动了  防止设置点击事件的时候 窗口移动松手后触发点击事件

        private boolean isMoved;

        //事件开始时和结束的时候  X和Y坐标位置

        private int startX;

        private int startY;

        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:

                    x = (int) event.getRawX();

                    y = (int) event.getRawY();

                    isMoved = false;

                    isScroll = false;

                    startX = (int) event.getRawX();

                    startY = (int) event.getRawY();

                    break;

                case MotionEvent.ACTION_MOVE:

                    int nowX = (int) event.getRawX();

                    int nowY = (int) event.getRawY();

                    int movedX = nowX - x;

                    int movedY = nowY - y;

                    x = nowX;

                    y = nowY;

                    layoutParams.x = layoutParams.x + movedX;

                    layoutParams.y = layoutParams.y + movedY;

// 更新悬浮窗控件布局

                    windowManager.updateViewLayout(view, layoutParams);

                    isScroll = true;

                    break;

                case MotionEvent.ACTION_UP:

                    int stopX = (int) event.getRawX();

                    int stopY = (int) event.getRawY();

                    if (Math.abs(startX - stopX) >= 1 || Math.abs(startY - stopY) >= 1) {

                        isMoved = true;

                    }

                    if (isScroll) {

//                        autoView(view);

                    }

                    break;

            }

            return isMoved;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 用户授予了录音权限，执行相应的操作
//                ToastUtils.showShort("获取录音权限成功");
            } else {
//                ToastUtils.showShort("用户拒绝了录音权限");
            }
        }
    }

    @Override
    protected void onDestroy() {
        if (floatView != null) {
            windowManager.removeViewImmediate(floatView);
            webView.loadUrl("");
            floatView = null;
        }
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            return;
        }

        this.doubleBackToExitPressedOnce = true;
        Toast.makeText(this, "再按一次返回键退出", Toast.LENGTH_SHORT).show();
        new Handler().postDelayed(() -> doubleBackToExitPressedOnce = false, 2000); // 设置间隔时间，单位为毫秒
    }
}